实现对定时器封装暂停恢复功能
const timeMap = Symbol('timeMap');
class Timer {
constructor() {
this[timeMap] = new Map();
}
/***
* 设置延时器,返回延时器ID
* @param callback
* @param ms
* @returns {number}
*/
setTimeout(callback, ms) {
let start_time = Date.now();
let need_time = ms;
let time_id = setTimeout(() => {
this.clear(time_id);
callback();
}, ms);
this[timeMap].set(time_id, {
start_time,
need_time,
is_run: true,
callback,
type: 'Timeout',
time_id: time_id
});
return time_id;
}
/***
* 设置定时器,返回定时器ID
* @param callback
* @param ms
* @returns {number}
*/
setInterval(callback, ms) {
let start_time = Date.now();
let need_time = ms;
let time_id = setInterval(() => {
callback();
}, ms);
this[timeMap].set(time_id, {
start_time,
need_time,
is_run: true,
callback,
type: 'Interval',
time_id: time_id
});
return time_id;
}
/***
* 停止定时器或延时器
* @param time_id
* @returns {boolean}
*/
stop(time_id) {
let time = this[timeMap].get(time_id);
if (time && time.is_run) {
let now_time = Date.now();
let type = time.type;
window[`clear${time.type}`](time.time_id);
if (type === 'Timeout') {
let need_time = time.need_time - (now_time - time.start_time);
if (need_time < 0) return;
time.need_time = need_time;
}
time.start_time = now_time;
time.is_run = false;
return true
}
}
/***
* 停止所有定时器和延时器
* @returns {boolean}
*/
stopAll() {
for (let key of this[timeMap].keys()) {
this.stop(key);
}
return true;
}
/***
* 恢复所有定时器和延时器
* @returns {boolean}
*/
restoreAll() {
for (let key of this[timeMap].keys()) {
this.restore(key);
}
return true;
}
/***
* 恢复定时器或延时器
* @param time_id
* @returns {boolean}
*/
restore(time_id) {
let time = this[timeMap].get(time_id);
if (time && !time.is_run) {
time.time_id = window[`set${time.type}`](() => {
time.callback();
time.type === 'Timeout' && this.clear(time_id);
}, time.need_time);
time.is_run = true;
return true;
}
}
/***
* 清除延时器或定时器
* @param time_id
* @returns {boolean}
*/
clear(time_id) {
let time = this[timeMap].get(time_id);
if (time) {
window[`clear${time.type}`](time.time_id);
this[timeMap].delete(time_id);
return true;
}
}
/***
* 清除全部定时器和延时器
* @returns {boolean}
*/
clearAll() {
for (let time of this[timeMap].values()) {
window[`clear${time.type}`](time.time_id);
}
this[timeMap].clear();
return true;
}
}